﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using IceTea.Domain.Models;
using IceTea.Security;
using IceTea.Domain;

namespace IceTea.Controllers
{
    public class ProductController : BaseController
    {
        #region View produt basic info
        // GET: /Project/
        [IceTeaAuthorize(SecurityRole.ProductViewer)]
        public ActionResult Index()
        {
            int curProjId = ((IceTeaPrincipal)User).RoleProfile.CurrentProductId;
            Product project = ProductFactory.GetProductById(curProjId);
            if (project == null)
                return RedirectToAction("Choose", "Product");
            
            return View(project);
        }

        [IceTeaAuthorize(SecurityRole.ProductViewer)]
        public PartialViewResult DisplayBasicInfo()
        {
            Product product = ProductFactory.GetProductById(IceTeaUser.RoleProfile.CurrentProductId);
            return PartialView("BasicInfo", product);
        }

        [IceTeaAuthorize(SecurityRole.ProductAdmin | SecurityRole.SuperAdmin
            | SecurityRole.ProductOwner | SecurityRole.ScrumMaster)]
        public PartialViewResult EditBasicInfo(int productId = -1)
        {
            Product product = null;
            if (productId > 0)
            {
                product = ProductFactory.GetProductById(productId);
            }
            else
            {
                product = new Product()
                {
                     Id = -1, 
                };
            }
            ViewBag.Result = IceTea.Infrastructure.EditResult.Start;
            return PartialView("EditBasicInfo", product);
        }

        [HttpPost]
        [IceTeaAuthorize(SecurityRole.ProductAdmin | SecurityRole.SuperAdmin
            | SecurityRole.ProductOwner | SecurityRole.ScrumMaster)]
        public ActionResult EditBasicInfo(Product product)
        {
            ViewBag.Result = IceTea.Infrastructure.EditResult.Fail;

            if(ModelState.IsValid)
            {
                if (ProductFactory.UpdateProductBasicInfo(product, IceTeaUser.RoleProfile.UserId) > 0)
                {
                    ViewBag.Result = IceTea.Infrastructure.EditResult.Success;
                    return PartialView("EditBasicInfo", null);
                }
            }
            return PartialView("EditBasicInfo", product);
        }
        #endregion

        #region Create product
        //Create New 
        [IceTeaAuthorize(SecurityRole.SuperAdmin)]
        public ViewResult CreateNew()
        {
            return View();
        }

        //Create New project post action
        [HttpPost]
        [IceTeaAuthorize(SecurityRole.SuperAdmin)]
        public ViewResult CreateNew(Product project)
        {
            if (!ModelState.IsValid)
            {
                return View(project);
            }

            IceTeaPrincipal user = User as IceTeaPrincipal;

            if (ProductFactory.CreateNewProduct(project, user.RoleProfile.UserId) < 0)
            {
                ModelState.AddModelError("", "Some error occurred when creating new product, please check out the log");
                return View(project);
            }
            return View("CreateSuccess");
        }
        #endregion

        #region Choose other product
        //Choose project
        public ActionResult Choose(int? pid)
        {
            IList<Product> products = ProductFactory.GetAllProducts();
            
            //Displaying the project choosing view
            if (pid.HasValue == false)
            {
                return View(products);
            }
            //one project is choosed
            else
            {
                IceTeaPrincipal principal = User as IceTeaPrincipal;
                if (!principal.RoleProfile.IsSuperAdmin && !principal.RoleProfile.ProductProfiles.ContainsKey(pid.Value))
                {
                    ModelState.AddModelError("", "You are not a member of this product, you have no authorize to access this project"); 
                    return View(products);
                }
                try
                {
                    ProductFactory.SwitchProduct(pid.Value, principal.RoleProfile.UserId);
                }
                catch (DomainException e)
                {
                    ModelState.AddModelError("", e.Message);
                    return View(products);
                }
                ClearRoleProfile(HttpContext);
                SetRoleProfile(HttpContext);
                
            }

            return RedirectToAction("Index", "Product"); 
        }
        #endregion

        #region Release
        /// <summary>
        /// Display the Releases of the current project
        /// </summary>
        /// <returns></returns>
        [IceTeaAuthorize(SecurityRole.ProductViewer)]
        public ActionResult ViewRelease()
        {
            return View();
        }

        [IceTeaAuthorize(SecurityRole.ProductViewer)]
        public PartialViewResult ReleaseList()
        {
            IEnumerable<Release> releases = ProductFactory.GetAllReleases(IceTeaUser.RoleProfile.CurrentProductId);
            return PartialView("ReleaseList", releases);
        }

        [IceTeaAuthorize(SecurityRole.ProductAdmin | SecurityRole.SuperAdmin
            | SecurityRole.ProductOwner | SecurityRole.ScrumMaster)]
        public PartialViewResult EditRelease(int releaseId = -1)
        {
            ViewBag.Result = IceTea.Infrastructure.EditResult.Start;
            Release release = new Release()
            {
                Id = -1, 
                ProductId = IceTeaUser.RoleProfile.CurrentProductId,
                StartDate = DateTime.Now,
                EndDate = DateTime.Now
            };
            if (releaseId > 0)
            {
                release = ProductFactory.GetRelease(releaseId);
            }

            return PartialView("EditRelease", release);
        }

        [HttpPost]
        [IceTeaAuthorize(SecurityRole.ProductAdmin | SecurityRole.SuperAdmin
            | SecurityRole.ProductOwner | SecurityRole.ScrumMaster)]
        public PartialViewResult EditRelease(Release release)
        {
            ViewBag.Result = IceTea.Infrastructure.EditResult.Fail;
            if (ModelState.IsValid)
            {
                if (release.Id <= 0)
                {
                    if (ProductFactory.AddNewRelease(release, IceTeaUser.RoleProfile.UserId) > 0)
                    {
                        ViewBag.Result = IceTea.Infrastructure.EditResult.Success;
                        return PartialView("EditRelease", null);
                    }
                }
                else
                {
                    if (ProductFactory.UpdateRelease(release, IceTeaUser.RoleProfile.UserId) > 0)
                    {
                        ViewBag.Result = IceTea.Infrastructure.EditResult.Success;
                        return PartialView("EditRelease", null);
                    }
                }
            }
            return PartialView("EditRelease", release);
        }

        #endregion

        #region View Teams of product
        //Display all teams info of a product
        [IceTeaAuthorize(SecurityRole.ProductViewer)]
        public ViewResult ViewTeams()
        {
            int curprodId = IceTeaUser.RoleProfile.CurrentProductId;
            IEnumerable<Team> teams = ProductFactory.GetProductTeams(curprodId);
            return View("Teams", teams);
        }

        //Show the team detailed info in a panel (users of the team, join requests)
        [IceTeaAuthorize(SecurityRole.ProductViewer)]
        public PartialViewResult GetTeamInfo(int teamId)
        {
            IEnumerable<TeamUser> teamusers = TeamFactory.GetTeamUsers(teamId);
            ViewBag.Team = TeamFactory.GetTeam(teamId);
            return PartialView("TeamInfo", teamusers);
        }

        //Deal wit the join request (approve or deny)
        [HttpPost]
        [IceTeaAuthorize(SecurityRole.ProductAdmin | SecurityRole.ProductOwner | 
                         SecurityRole.SuperAdmin | SecurityRole.ScrumMaster)]
        public PartialViewResult DealJoinRequest(int teamuserId, bool approve)
        {
            int state = approve ? (int)TeamUserState.Approved : (int)TeamUserState.Denied;
            TeamFactory.UpdateTeamUserState(teamuserId, state);
            return PartialView("_InfoMessage", 
                string.Format("The request has been {0}", (approve? "approved":"denied")));
        }

        //send the request to join the team
        [IceTeaAuthorize(SecurityRole.ValidUser)]
        [HttpPost]
        public PartialViewResult RequestJoinTeam()
        {
            int teamId = int.Parse(Request.Form["TeamId"]);
            int userId = IceTeaUser.RoleProfile.UserId;
            List<int> roles = new List<int>();
            if (Request.Form["RoleProductOwner"].Contains("true"))
            {
                roles.Add((int)ScrumRole.ProductOwner);
            }
            if (Request.Form["RoleScrumMaster"].Contains("true"))
            {
                roles.Add((int)ScrumRole.ScrumMaster);
            }
            if (Request.Form["RoleDevelopmentTeam"].Contains("true"))
            {
                roles.Add((int)ScrumRole.DevelopmentTeam);
            }
            if (Request.Form["RoleStakeholder"].Contains("true"))
            {
                roles.Add((int)ScrumRole.Stakeholder);
            }
            if (TeamFactory.RequestJoinTeam(teamId, userId, roles) > 0)
            {
                return PartialView("_InfoMessage", 
                    "The request to join the team has been sent, you will be member of the team after your request be approved");
            }
            return PartialView("_ErrorMessge", "Failed to send your request to join the team");
        }
        #endregion

        #region Product Backlog
        [IceTeaAuthorize(SecurityRole.ProductViewer)]
        public ViewResult ProductBacklog()
        {
            return View();
        }

        [IceTeaAuthorize(SecurityRole.ProductViewer)]
        public PartialViewResult ListPBIs()
        {
            IEnumerable<PBI> pbilist = PBIFactory.GetProductRootPBIs(IceTeaUser.RoleProfile.CurrentProductId);
            return PartialView("PBIList", pbilist);
        }

        [IceTeaAuthorize(SecurityRole.ProductViewer)]
        public PartialViewResult CreatePBI()
        {
            return PartialView("PBIEdit", null);
        }
        #endregion
    }
}
